package sdk.zy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;

import sdk.common.MySSLSocketFactory;
import sdk.garena.SDKConstants;

public class WeiXinOpenApi {

	private static Logger logger = LoggerFactory.getLogger(WeiXinOpenApi.class);

	static class SingletonHolder {
		static WeiXinOpenApi instance = new WeiXinOpenApi();
	}

	public static WeiXinOpenApi getInstance() {
		return SingletonHolder.instance;
	}

	public Map<String, Object> verifylogin(String appId, String appSecret, String code) {
		String requestUrlPath = "https://api.weixin.qq.com/sns/oauth2/access_token";
		String requestParams = String.format("appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code", appId,
				appSecret, code);
		Map<String, Object> retMap = doHttpsGet(requestUrlPath, requestParams);
		return retMap;
	}

	public Map<String, Object> refreshToken(String appId, String refresh_token) {
		String requestUrlPath = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
		String requestParams = String.format("appid=%1$s&refresh_token=%2$s&grant_type=refresh_token", appId,
				refresh_token);
		Map<String, Object> retMap = doHttpsGet(requestUrlPath, requestParams);
		return retMap;
	}

	public Map<String, Object> get_userinfo(String accessToken, String openId) {
		String requestUrlPath = "https://api.weixin.qq.com/sns/userinfo";
		String requestParams = String.format("access_token=%1$s&openid=%2$s", accessToken, openId);
		Map<String, Object> retMap = doHttpsGet(requestUrlPath, requestParams);
		return retMap;
	}

	private Map<String, Object> doHttpsGet(String requestUrlPath, String requestParams) {
		String result = "";
		BufferedReader in = null;
		try {
			SSLSocketFactory ssf = MySSLSocketFactory.getInstance().getSSLSocketFactory();

			URL realUrl = new URL(requestUrlPath + "?" + requestParams);
			logger.info("open connection!,url={}://{}{}?{}", realUrl.getProtocol(), realUrl.getHost(),
					realUrl.getPath(), realUrl.getQuery());
			// 打开和URL之间的连接
			HttpsURLConnection connection = (HttpsURLConnection) realUrl.openConnection();
			connection.setSSLSocketFactory(ssf);
			// 设置通用的请求属性
			connection.setConnectTimeout(SDKConstants.CONNECTION_TIMEOUT);
			connection.setRequestProperty("accept", "*/*");
			connection.setRequestProperty("connection", "Keep-Alive");
			connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			// GET请求
			connection.setRequestMethod("GET");
			// 建立实际的连接
			connection.connect();
			logger.info("send request,url={}://{}{}", realUrl.getProtocol(), realUrl.getHost(), realUrl.getPath());
			// 定义 BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
			return extractPostParams(result);
		} catch (Exception e) {
			logger.error("发送POST请求出现异常！", e);
		}
		// 使用finally块来关闭输入流
		finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				logger.error("关闭http请求出现异常！", e2);
			}
		}
		return null;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map<String, Object> extractPostParams(String queryString) {
		// URLDecoder.decode(queryString, "UTF-8");
		ObjectMapper mapper = new ObjectMapper();
		Map quizAnswer = null;
		try {
			quizAnswer = mapper.readValue(queryString, Map.class);
		} catch (IOException e) {
			logger.error("", e);
		}
		return quizAnswer;
	}

	public static void main(String[] args) {
		String appId = "wx1e4011757923db11";
		String appSecret = "1b493ca03ac7d12b89a74724671f8799";
		String code = "031Jmzdr1nisYq05jogr122Bdr1JmzdK";
		Map<String, Object> retMap = WeiXinOpenApi.getInstance().verifylogin(appId, appSecret, code);
		logger.info("retMap={}", retMap);
	}

}
